03 Activity之间传递参数

一、传递简单数据

发送数据:

1
2
3
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("data", "data value");
startActivity(intent);

接受数据:

1
2
String data = getIntent().getStringExtra("data");
textView.setText(data);

优化代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 传递参数
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendArgs(View view) {
Intent intent = OtherActivity.newIntent(this, "data value");
startActivity(intent);
}
}
// 接受参数
public class OtherActivity extends AppCompatActivity {
private static final String ARG = "data";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
TextView textView = (TextView) findViewById(R.id.tv);
String data = getIntent().getStringExtra(ARG);
textView.setText(data);
}
// 解除参数名称"data"带来的依赖性
public static Intent newIntent(Context context, String data) {
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra(ARG, data);
return intent;
}
}

二、传递数据包Bundle

发送数据包:

1
2
3
4
5
6
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "xian xiaotao");
bundle.putInt("age", 28);
intent.putExtras(bundle);
startActivity(intent);

接受数据包:

1
2
Bundle data = getIntent().getExtras();
textView.setText(String.format(Locale.getDefault(), "name=%s,age=%d", data.getString("name"), data.getInt("age")));

三、传递值对象

实现Parcelable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
private String mName;
private int mAge;
public User(String name, int age) {
mName = name;
mAge = age;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public int getAge() {
return mAge;
}
public void setAge(int age) {
mAge = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// 更复杂的数据借用Bundle
dest.writeString(getName());
dest.writeInt(getAge());
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source.readString(), source.readInt());
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}

传递参数:

1
2
3
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("user", new User("xian xiaotao", 28));
startActivity(intent);

接收参数

1
2
User user = getIntent().getParcelableExtra("user");
textView.setText(String.format(Locale.getDefault(), "name=%s,age=%d", user.getName(), user.getAge()));

Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

四、获取Activity返回参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class QuizActivity extends AppCompatActivity {
private static final int REQUEST_CODE_CHEAT = 0;
...
// startActivityForResult代码
Intent i = CheatActivity.newIntent(QuizActivity.this, answerIsTrue);
startActivityForResult(i, REQUEST_CODE_CHEAT);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK)
return;
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null)
return;
mIsCheater = CheatActivity.wasAnswerShown(data);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CheatActivity extends AppCompatActivity {
private static final String EXTRA_ANSWER_SHOWN = "com.xxtking.geoquiz.CheatActivity.answer_shown";
...
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
public static boolean wasAnswerShown(Intent result) {
return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}
}